package cn.pluss.baselibrary.http;

import android.arch.lifecycle.LifecycleOwner;
import android.support.annotation.NonNull;

import com.alibaba.fastjson.JSONObject;
import com.hjq.toast.ToastUtils;
import com.orhanobut.logger.Logger;
import com.uber.autodispose.AutoDispose;
import com.uber.autodispose.android.lifecycle.AndroidLifecycleScopeProvider;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import cn.pluss.baselibrary.http.callback.SimpleHttpCallBack;
import cn.pluss.baselibrary.http.exception.ApiException;
import cn.pluss.baselibrary.model.net.ResultPageListBean;
import cn.pluss.baselibrary.model.net.SvcContBean;
import cn.pluss.baselibrary.model.net.TcpContBean;
import io.reactivex.Observable;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import okhttp3.RequestBody;


public class PostRequest {

    public static final String TAG = "PostRequest";

    private String mInterfaceName;
    private HashMap<String, Object> mParams;


    public PostRequest(String interfaceName) {
        mInterfaceName = interfaceName;
        mParams = new HashMap<>();
    }

    public PostRequest params(String key, Object value) {
        mParams.put(key, value);
        return this;
    }

    public PostRequest params(HashMap<String, Object> params) {
        mParams = params;
        return this;
    }

    public PostRequest params(Object object) {
        String json = JSONObject.toJSONString(object);
        mParams = JSONObject.parseObject(json, HashMap.class);
        return this;
    }

    public Observable<String> stringObservableDelayError() {
        RequestBody requestBody = createRequestBody();
        return RetrofitClient.getApiService().request(requestBody)
                .compose(RxUtils.rxTranslate2Msg())
                .onErrorReturn(new Function<Throwable, String>() {
                    @Override
                    public String apply(Throwable throwable){
                        ToastUtils.show(ApiException.handleException(throwable).getMessage());
                        return "";
                    }
                })
                .subscribeOn(Schedulers.io());
    }

    public Observable<String> stringObservable() {
        RequestBody requestBody = createRequestBody();
        return RetrofitClient.getApiService().request(requestBody)
                .compose(RxUtils.rxTranslate2Msg())
                .subscribeOn(Schedulers.io());
    }

    public Single<String> stringSingle() {
        RequestBody requestBody = createRequestBody();
        return RetrofitClient.getApiService().requestSingle(requestBody)
                .compose(RxUtils.rxTranslate2MsgSingle())
                .subscribeOn(Schedulers.io());
    }

    public <T> Observable<T> beanObservableDelayError(final Class<T> clazz) {
        RequestBody requestBody = createRequestBody();
        return RetrofitClient.getApiService().request(requestBody)
                .compose(RxUtils.rxTranslate2Bean(clazz))
                .onErrorReturn(new Function<Throwable, T>() {
                    @Override
                    public T apply(Throwable throwable) throws Exception{
                        ToastUtils.show(ApiException.handleException(throwable).getMessage());
                        return clazz.newInstance();
                    }
                })
                .subscribeOn(Schedulers.io());
    }

    public <T> Observable<T> beanObservable(Class<T> clazz) {
        RequestBody requestBody = createRequestBody();
        return RetrofitClient.getApiService().request(requestBody)
                .compose(RxUtils.rxTranslate2Bean(clazz))
                .subscribeOn(Schedulers.io());
    }

    public <T> Single<T> beanObservableSingle(Class<T> clazz) {
        RequestBody requestBody = createRequestBody();
        return RetrofitClient.getApiService().requestSingle(requestBody)
                .compose(RxUtils.rxTranslate2BeanSingle(clazz))
                .subscribeOn(Schedulers.io());
    }

    public <T> Observable<ArrayList<T>> listObservableDelayError(Class<T> clazz) {
        RequestBody requestBody = createRequestBody();
        return RetrofitClient.getApiService().request(requestBody)
                .compose(RxUtils.rxTranslate2List(clazz))
                .onErrorReturn(new Function<Throwable, ArrayList<T>>() {
                    @Override
                    public ArrayList<T> apply(Throwable throwable){
                        ToastUtils.show(ApiException.handleException(throwable).getMessage());
                        return new ArrayList<>();
                    }
                })
                .subscribeOn(Schedulers.io());
    }

    public <T> Observable<ArrayList<T>> listObservable(Class<T> clazz) {
        RequestBody requestBody = createRequestBody();
        return RetrofitClient.getApiService().request(requestBody)
                .compose(RxUtils.rxTranslate2List(clazz))
                .subscribeOn(Schedulers.io());
    }


    public <T> PostRequest execute(Class<T> clazz, final SimpleHttpCallBack<T> callBack) {
        RequestBody requestBody = createRequestBody();
        RetrofitClient.getApiService().request(requestBody)
                .compose(RxUtils.rxTranslate2Bean(clazz))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .unsubscribeOn(Schedulers.io())
                .as(AutoDispose.<T>autoDisposable(AndroidLifecycleScopeProvider.from(mLifecycleOwner)))
                .subscribe(new BaseObserver<T>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        callBack.onStart();
                        //mBaseView.showLoading();
                    }

                    @Override
                    public void onNext(T t) {
                        callBack.onSuccess(t);
                    }

                    @Override
                    public void onError(ApiException e) {
                        callBack.onError(e);
                        //mBaseView.showError(e.getMessage());
                        //mBaseView.hideLoading();
                    }

                    @Override
                    public void onComplete() {
                        callBack.onCompleted();
                        //mBaseView.hideLoading();
                        //mBaseView = null;
                    }
                });

        return this;
    }

    @NonNull
    public RequestBody createRequestBody() {
        String s = composeRequestMessage(mInterfaceName, mParams);
        Logger.json(s);
        return RequestBody.create(okhttp3.MediaType.parse("application/json;charset=UTF-8"), s);
    }

    private LifecycleOwner mLifecycleOwner;
    public PostRequest bindLifecycle(LifecycleOwner lifecycleOwner) {
        mLifecycleOwner = lifecycleOwner;
        return this;
    }


    public <T> PostRequest executeArray(Class<T> clazz, final SimpleHttpCallBack<T> callBack) {
        RequestBody requestBody = createRequestBody();
        RetrofitClient.getApiService().request(requestBody)
                .compose(RxUtils.rxTranslate2List(clazz))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .unsubscribeOn(Schedulers.io())
                .as(AutoDispose.<ArrayList<T>>autoDisposable(AndroidLifecycleScopeProvider.from(mLifecycleOwner)))
                .subscribe(new BaseObserver<ArrayList<T>>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        callBack.onStart();
                    }

                    @Override
                    public void onNext(ArrayList<T> t) {
                        callBack.onSuccess(t);

                    }

                    @Override
                    public void onError(ApiException e) {
                        callBack.onError(e);
                    }

                    @Override
                    public void onComplete() {
                        callBack.onCompleted();
                    }
                });
        return this;
    }

    public <T> void executePage(Class<T> tClass, final SimpleHttpCallBack<T> callBack) {
        RetrofitClient.getApiService().request(createRequestBody())
                .compose(RxUtils.rxTranslate2PageBean(tClass))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .unsubscribeOn(Schedulers.io())
                .as(AutoDispose.<ResultPageListBean<T>>autoDisposable(AndroidLifecycleScopeProvider.from(mLifecycleOwner)))
                .subscribe(new BaseObserver<ResultPageListBean<T>>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        callBack.onStart();
                    }

                    @Override
                    public void onNext(ResultPageListBean<T> tResultPageListBean) {
                        callBack.onSuccess(tResultPageListBean);
                    }

                    @Override
                    public void onComplete() {
                        callBack.onCompleted();
                    }

                    @Override
                    public void onError(ApiException e) {
                        callBack.onError(e);

                    }
                });

    }

    public PostRequest execute(final SimpleHttpCallBack<String> callBack) {
        RetrofitClient.getApiService().request(createRequestBody())
                .compose(RxUtils.rxTranslate2Msg())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .unsubscribeOn(Schedulers.io())
                .as(AutoDispose.<String>autoDisposable(AndroidLifecycleScopeProvider.from(mLifecycleOwner)))
                .subscribe(new BaseObserver<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        callBack.onStart();
                    }

                    @Override
                    public void onNext(String msg) {
                        callBack.onSuccess(msg);
                    }

                    @Override
                    public void onComplete() {
                        callBack.onCompleted();
                    }

                    @Override
                    public void onError(ApiException e) {
                        callBack.onError(e);
                    }
                });
        return this;
    }

    public PostRequest execute(Object object,final SimpleHttpCallBack<String> callBack) {
        String s = composeRequestMessage(mInterfaceName, object);
        Logger.json(s);
        RequestBody requestBody = RequestBody.create(okhttp3.MediaType.parse("application/json;charset=UTF-8"), s);
        RetrofitClient.getApiService().request(requestBody)
                .compose(RxUtils.rxTranslate2Msg())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .unsubscribeOn(Schedulers.io())
                .as(AutoDispose.<String>autoDisposable(AndroidLifecycleScopeProvider.from(mLifecycleOwner)))
                .subscribe(new BaseObserver<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        callBack.onStart();
                        //mBaseView.showLoading();
                    }

                    @Override
                    public void onNext(String msg) {
                        callBack.onSuccess(msg);
                    }

                    @Override
                    public void onComplete() {
                        super.onComplete();
                        callBack.onCompleted();
                        //mBaseView.hideLoading();
                        //mBaseView = null;
                    }

                    @Override
                    public void onError(ApiException e) {
                        callBack.onError(e);
                        //mBaseView.hideLoading();
                        //mBaseView.showError(e.getMessage());
                    }
                });
        return this;
    }


    public static String composeRequestMessage(String setServiceCode, Object params) {
        TcpContBean tcpCont = new TcpContBean();
        tcpCont.setSrcSysID("1003");
        tcpCont.setServiceCode(setServiceCode);
        tcpCont.setSrcSysPassWord("1003");
        tcpCont.setSrcSysSign("123456");
        tcpCont.setTransactionID("1322017119413");
        List<SvcContBean> svContLst = new ArrayList<>();
        SvcContBean svcCont = new SvcContBean();
        svcCont.setParams(params);
        svContLst.add(svcCont);
        Map<String, Object> map = new HashMap<>();
        map.put("SvcCont", svContLst);
        map.put("TcpCont", tcpCont);
        return JSONObject.toJSONString(map);
    }
}
